package cn.johnyu.config;

import cn.johnyu.filter.CheckTokenFilter;
import cn.johnyu.service.AuthenPersistenceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.ReactiveAuthenticationManager;
import org.springframework.security.authentication.UserDetailsRepositoryReactiveAuthenticationManager;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.SecurityWebFiltersOrder;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.core.userdetails.ReactiveUserDetailsService;
import org.springframework.security.web.server.SecurityWebFilterChain;

@Configuration
@EnableWebFluxSecurity
public class SecurityConfig {
    @Autowired
    private AuthenPersistenceService authenPersistenceService;
    @Bean
    public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
        return http.csrf(csrfSpec -> csrfSpec.disable())
                .formLogin(formLoginSpec -> formLoginSpec.disable())
                .httpBasic(httpBasicSpec -> httpBasicSpec.disable())
                .logout(logoutSpec -> logoutSpec.disable())
                .authorizeExchange(authorizeExchangeSpec -> authorizeExchangeSpec
                        .pathMatchers("/login").permitAll()
                        .pathMatchers(HttpMethod.GET,"/api/book-service/books").hasAnyRole("ADMIN","USER")
                        .pathMatchers(HttpMethod.POST,"/api/book-service/books").hasAnyRole("ADMIN")
                        .anyExchange().authenticated()
                )
                .addFilterBefore(new CheckTokenFilter(authenPersistenceService), SecurityWebFiltersOrder.AUTHORIZATION)
                .build();
    }
    //使用自定义的认证管理器，替换原有的，并且注入自定义的UserDetailsService
    @Bean
    public ReactiveAuthenticationManager reactiveAuthenticationManager(ReactiveUserDetailsService detailsService) {
        return new UserDetailsRepositoryReactiveAuthenticationManager(detailsService);
    }
}
